#pragma once

ref class CqSdk : CsCQ_Core::ICqSdk
{
public:
	CqSdk(int ac);

	int virtual SendMessage(int64_t id, System::String^ p_message)
	{
		auto message = GetCharFormString(p_message);
		auto result = CQ_sendPrivateMsg(_ac, id, message);

		FreeHGlobal(message);

		return result;
	}

	int virtual SendGroupMessage(int64_t p_groupid, System::String^ p_message)
	{
		auto message = GetCharFormString(p_message);
		auto result = CQ_sendGroupMsg(_ac, p_groupid, message);

		FreeHGlobal(message);

		return result;
	}
	int virtual SendDiscussMessage(int64_t p_groupid, System::String^ p_message)
	{
		auto message = GetCharFormString(p_message);
		auto result = CQ_sendDiscussMsg(_ac, p_groupid, message);

		FreeHGlobal(message);

		return result;
	}

	int virtual Log(CsCQ_Core::Enum::LogMode p_mode, System::String^ p_title, System::String^ p_message)
	{
		auto title = GetCharFormString(p_title);
		auto message = GetCharFormString(p_message);

		auto result = CQ_addLog(_ac, (int)p_mode, title, message);

		FreeHGlobal(title);
		FreeHGlobal(message);

		return result;
	}

	int virtual Fatal(System::String^ errorinfo)
	{
		auto error = GetCharFormString(errorinfo);
		auto result = CQ_setFatal(_ac, error);

		FreeHGlobal(error);

		return result;
	}

	int virtual SendLike(int64_t id)
	{
		return CQ_sendLike(_ac, id);
	}

	int virtual SetGroupKick(int64_t groupid, int64_t id, bool rejectaddrequest)
	{
		return CQ_setGroupKick(_ac, groupid, id, rejectaddrequest);
	}

	int virtual SetGroupBan(int64_t groupid, int64_t id, int64_t duration)
	{
		return CQ_setGroupBan(_ac, groupid, id, duration);
	}

	int virtual SetGroupAdmin(int64_t groupid, int64_t id, bool setadmin)
	{
		return CQ_setGroupAdmin(_ac, groupid, id, setadmin);
	}

	int virtual SetGroupWholeBan(int64_t groupid, bool enableban)
	{
		return CQ_setGroupWholeBan(_ac, groupid, enableban);
	}

	int virtual SetGroupAnonymousBan(int64_t groupid, System::String^ p_anomymous, int64_t duration)
	{
		auto anomymous = GetCharFormString(p_anomymous);
		auto result = CQ_setGroupAnonymousBan(_ac, groupid, anomymous, duration);

		FreeHGlobal(anomymous);

		return result;
	}

	int virtual SetGroupAnonymous(int64_t groupid, bool enableanomymous)
	{
		return CQ_setGroupAnonymous(_ac, groupid, enableanomymous);
	}

	int virtual SetGroupCard(int64_t groupid, int64_t id, System::String^ newcard)
	{
		auto card = GetCharFormString(newcard);
		auto result = CQ_setGroupCard(_ac, groupid, id, card);

		FreeHGlobal(card);

		return result;
	}

	int virtual SetGroupLeave(int64_t groupid, bool isdismiss)
	{
		return CQ_setGroupLeave(_ac, groupid, isdismiss);
	}

	int virtual SetGroupSpecialTitle(int64_t groupid, int64_t id, System::String^ newspecialtitle, int64_t duration)
	{
		auto title = GetCharFormString(newspecialtitle);
		auto result = CQ_setGroupSpecialTitle(_ac, groupid, id, title, duration);

		FreeHGlobal(title);

		return result;
	}

	int virtual SetDiscussLeave(int64_t discussid)
	{
		return CQ_setDiscussLeave(_ac, discussid);
	}

	int virtual SetFriendAddRequest(System::String^ p_responseflag, int responseoperation, System::String^ p_remark)
	{
		auto flag = GetCharFormString(p_responseflag);
		auto remark = GetCharFormString(p_remark);
		auto result = CQ_setFriendAddRequest(_ac, flag, responseoperation, remark);

		FreeHGlobal(flag);
		FreeHGlobal(remark);

		return result;
	}

	int virtual SetGroupAddRequestV2(System::String^ p_responseflag, CsCQ_Core::Enum::RequstMode requesttype, int responseoperation, System::String^ p_reason)
	{
		auto flag = GetCharFormString(p_responseflag);
		auto reason = GetCharFormString(p_reason);

		auto result = CQ_setGroupAddRequestV2(_ac, flag, (int32_t)requesttype, responseoperation, reason);

		FreeHGlobal(flag);
		FreeHGlobal(reason);

		return result;
	}

	virtual System::String^ GetGroupMemberInfoV2(int64_t groupid, int64_t id, bool nocache)
	{
		auto info = CQ_getGroupMemberInfoV2(_ac, groupid, id, nocache);
		return gcnew System::String(info);
	}

	virtual System::String^ GetStrangerInfo(int64_t id, bool nocache)
	{
		auto info = CQ_getStrangerInfo(_ac, id, nocache);

		return gcnew System::String(info);
	}

	virtual System::String^ GetCookies()
	{
		auto cookies = CQ_getCookies(_ac);

		return gcnew System::String(cookies);
	}

	int virtual GetCsrfToken()
	{
		return CQ_getCsrfToken(_ac);
	}

	int64_t virtual GetLoginQQ()
	{
		return CQ_getLoginQQ(_ac);
	}

	virtual System::String^ GetLoginNick()
	{
		auto nick = CQ_getLoginNick(_ac);

		return gcnew System::String(nick);
	}

	virtual System::String^ GetAppDirectory()
	{
		auto dir = CQ_getAppDirectory(_ac);

		return gcnew  System::String(dir);
	}

	static CqSdk^ Default;

private:
	int _ac = -1;

	char* GetCharFormString(System::String^ p_input)
	{
		return (char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(p_input).ToPointer();
	}

	void FreeHGlobal(void* p)
	{
		System::Runtime::InteropServices::Marshal::FreeHGlobal((System::IntPtr)p);
	}
};

